package com.ibaodashi.gxing.activity;

import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;


/**
 * desc   :
 * author : guowenlong
 * Email  : guowenlong20000@gmail.com
 * time   : 2018年11月30日17 : 02
 */
public class LoopHandler extends Handler {
    public static final int DISENABLE = 0;
    public static final int ENABLE = 1;
    public static final int START = 2;
    public static final int DECODE = 3;
    private int mState = DECODE;
    private boolean running = false;
    private final Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
    private final MultiFormatReader multiFormatReader;
    public int cameraPreviewHeight;
    public int cameraPreviewWidth;

    public LoopHandler(int width, int height) {
        Collection<BarcodeFormat> decodeFormats = new ArrayList<>();
        decodeFormats.addAll(EnumSet.of(BarcodeFormat.AZTEC));
        decodeFormats.addAll(EnumSet.of(BarcodeFormat.PDF_417));
        decodeFormats.addAll(DecodeFormatManager.getBarCodeFormats());
        decodeFormats.addAll(DecodeFormatManager.getQrCodeFormats());
        hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
        multiFormatReader = new MultiFormatReader();
        multiFormatReader.setHints(hints);
        cameraPreviewHeight = height;
        cameraPreviewWidth = width;
    }

    @Override
    public void handleMessage(Message message) {
        if (mState == DISENABLE) return;
        if (running) return;

        if (message.what == DECODE) {
            byte[] obj = (byte[]) message.obj;
            if (obj == null || obj.length == 0) return;
            decode(obj, message.arg1, message.arg2, cameraPreviewWidth, cameraPreviewHeight);
            Log.e("loop", "handleMessage");
        }
    }

    private void decode(byte[] data, int width, int height, int _previewWidth, int _previewHeight) {
        int previewWidth = _previewWidth;
        int previewHeight = _previewHeight;

        // 这里需要将获取的data翻转一下，因为相机默认拿的的横屏的数据
        byte[] rotatedData = new byte[data.length];
        for (int y = 0; y < previewHeight; y++) {
            for (int x = 0; x < previewWidth; x++)
                rotatedData[x * previewHeight + previewHeight - y - 1] = data[x + y * previewWidth];
        }

        // 宽高也要调整
        int tmp = previewWidth;
        previewWidth = previewHeight;
        previewHeight = tmp;

        Result rawResult = null;
        PlanarYUVLuminanceSource source = buildLuminanceSource(rotatedData, previewWidth, previewHeight);
        if (source != null) {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            try {
                rawResult = multiFormatReader.decodeWithState(bitmap);
                Log.e("LoopHandler", rawResult.getText());
            } catch (ReaderException re) {
                // continue
            } finally {
                multiFormatReader.reset();
            }
        }

//        Handler handler = activity.getHandler();
//        if (rawResult != null) {
//            // Don't log the barcode contents for security.
//            if (handler != null) {
//                Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
//                Bundle bundle = new Bundle();
//                bundleThumbnail(source, bundle);
//                message.setData(bundle);
//                message.sendToTarget();
//            }
//        } else {
//            if (handler != null) {
//                Message message = Message.obtain(handler, R.id.decode_failed);
//                message.sendToTarget();
//            }
//        }
    }

    public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {

        // Go ahead and assume it's YUV rather than die.
        return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
    }
}